package indi.mozping.concurrentutil.cyclicbarrierp;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CyclicBarrier;

/**
 * @author by mozping
 * @Classname Solver
 * @Description ����CyclicBarrierԴ���е�demoд��
 * @Date 2019/5/24 14:46
 */
public class Solver1 {

    //����flag��ʾ�����Ƿ����
    static private volatile boolean flag = false;

    /**
     * �����̣߳�����ѭ���������飬��N�δ�������Ὣ�����ǰN��Ԫ����ͣ���������������������λ��
     */
    static class Worker implements Runnable {
        int row;
        float[][] data;
        CyclicBarrier cyclicBarrier;
        //��¼ѭ���Ĵ���
        int index = 0;

        public Worker(int row, float[][] data, CyclicBarrier cyclicBarrier) {
            this.row = row;
            this.data = data;
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            while (!done()) {
                processRow(row);
                index++;//������֮���±��1
                try {
                    cyclicBarrier.await();
                } catch (Exception e) {
                    return;
                }
            }
        }

        private void processRow(int row) {
            //��С�괦��Ԫ���ۼӵ����
            data[row][10000] += data[row][index];
            System.out.println("�̣߳�" + Thread.currentThread().getName() + "�����" + row +
                    "�е�" + index + "��...");
        }

        private boolean done() {
            return flag;
        }
    }

    /**
     * �ϲ��̣߳�����ۼӵĽ��֮�ʹ�����ֵ���������������֮����������ۼ�
     */
    static class MergeRows implements Runnable {

        final float[][] data;
        //��ֵ
        final int threshold;

        public MergeRows(float[][] data, int threshold) {
            this.data = data;
            this.threshold = threshold;
        }

        @Override
        public void run() {
            float result = 0;
            System.out.println("MergeRows ��ʼMerge..." + Thread.currentThread().getName());
            //�ۼӽ��
            for (int i = 0; i < 10; i++) {
                result += data[i][10000];
            }
            try {
                Thread.sleep(3000);
                System.out.println("MergeRows ��Ϻķ�3000ms ," + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //ȷ���Ƿ��ж�����
            if (result > threshold) {
                System.out.println("MergeRows �ɹ� �������: " + result);
                flag = true;
            } else {
                System.out.println("MergeRows ʧ�� �������: " + result);
                flag = false;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        float[][] data = new float[10][10001];
        Random random = new Random();
        //1.��ʼ������
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10000; j++) {
                data[i][j] = random.nextInt(100);
            }
        }
        System.out.println("��ʼ��data���...");
        //2.��ʼ��դ��
        CyclicBarrier cyclicBarrier = new CyclicBarrier(10, new MergeRows(data, 2000));

        List<Thread> threads = new ArrayList<>(10);
        //3.�����߳�
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new Worker(i, data, cyclicBarrier));
            threads.add(thread);
            thread.start();
        }

        //4.���̵߳ȴ����ڹ����߳�֮���ٽ���
        for (Thread thread : threads) {
            thread.join();
        }
    }
}
